home *** CD-ROM | disk | FTP | other *** search
/ IRIX 6.3 Development Libraries / SGI IRIX 6.3 Development Libraries.iso / dist6.3 / gl_dev.idb / usr / share / src / OpenGL / toolkits / libwidget / GLwDrawA.c.z / GLwDrawA.c
Encoding:
C/C++ Source or Header  |  1996-12-06  |  21.7 KB  |  700 lines

  1. #include <X11/IntrinsicP.h>
  2. #include <X11/StringDefs.h>
  3. #include <GL/glx.h>
  4. #include <GL/gl.h>
  5. #ifdef __GLX_MOTIF
  6. #include <Xm/PrimitiveP.h>
  7. #include <X11/GLw/GLwMDrawAP.h>
  8. #else /* not __GLX_MOTIF */
  9. #include <X11/GLw/GLwDrawAP.h>
  10. #endif /* __GLX_MOTIF */
  11. #include <assert.h>
  12.  
  13. #ifdef __GLX_MOTIF
  14. /* The MOTIF version differs only in the inclusion of the primitive
  15.  * widget class and in a vew variable and type name differences.
  16.  * Rather than put ifdefs all over the place, we just use a few defines
  17.  * to make it use motif types and names
  18.  */
  19. #define GLwDrawingAreaWidget        GLwMDrawingAreaWidget
  20. #define GLwDrawingAreaClassRec        GLwMDrawingAreaClassRec
  21. #define glwDrawingAreaClassRec        glwMDrawingAreaClassRec
  22. #define glwDrawingAreaWidgetClass    glwMDrawingAreaWidgetClass
  23. #define GLwDrawingAreaRec        GLwMDrawingAreaRec
  24. #endif /* __GLX_MOTIF */
  25.  
  26. /* forward definitions */
  27. /* resource default procs */
  28. static void createColormap(GLwDrawingAreaWidget w,
  29.                int offset, XrmValue *value);
  30.  
  31. /* widget methods */
  32. static void Initialize(GLwDrawingAreaWidget req, GLwDrawingAreaWidget new,
  33.                ArgList args, Cardinal *num_args);
  34. static void Realize(Widget w, Mask *valueMask,
  35.             XSetWindowAttributes *attributes);
  36. static void Redraw(GLwDrawingAreaWidget w, XEvent *event, Region region);
  37. static void Resize(GLwDrawingAreaWidget glw);
  38. static void Destroy(GLwDrawingAreaWidget glw);
  39.  
  40. #define offset(field) XtOffset(GLwDrawingAreaWidget, glwDrawingArea.field)
  41.  
  42. static char defaultTranslations[] =
  43. #ifdef __GLX_MOTIF
  44.      "<Key>osfHelp:PrimitiveHelp() \n"
  45. #endif
  46.     "<KeyDown>:    glwInput() \n\
  47.      <KeyUp>:    glwInput() \n\
  48.      <BtnDown>: glwInput() \n\
  49.      <BtnUp>:   glwInput() \n\
  50.      <BtnMotion>: glwInput() ";
  51.  
  52. static void glwInput(GLwDrawingAreaWidget glw, XEvent *event,
  53.               String *, Cardinal *);
  54.  
  55. static XtActionsRec actions[] = {
  56.     { "glwInput", (XtActionProc) glwInput },    /* key or mouse input */
  57. };
  58.  
  59. /*
  60.  * There is a bit of unusual handling of the resources here.
  61.  * Because Xt insists on allocating the colormap resource when it is
  62.  * processing the core resources (even if we redeclare the colormap
  63.  * resource here, we need to do a little trick.  When Xt first allocates
  64.  * the colormap, we allow it to allocate the default one, since we have
  65.  * not yet determined the appropriate visual (which is determined from
  66.  * resources parsed after the colormap).  We also let it allocate colors
  67.  * in that default colormap.
  68.  *
  69.  * In the initialize proc we calculate the actual visual.  Then, we
  70.  * reobtain the colormap resource using XtGetApplicationResources in
  71.  * the initialize proc.  If requested, we also reallocate colors in
  72.  * that colormap using the same method.
  73.  */
  74.  
  75. static XtResource resources[] = {
  76.   /* The GLX attributes.  Add any new attributes here */
  77.  
  78.   {GLwNbufferSize, GLwCBufferSize, XtRInt, sizeof (int),
  79.        offset(bufferSize), XtRImmediate, (XtPointer) 0},
  80.   
  81.   {GLwNlevel, GLwCLevel, XtRInt, sizeof (int),
  82.        offset(level), XtRImmediate, (XtPointer) 0},
  83.   
  84.   {GLwNrgba, GLwCRgba, XtRBoolean, sizeof (Boolean),
  85.        offset(rgba), XtRImmediate, (XtPointer) FALSE},
  86.   
  87.   {GLwNdoublebuffer, GLwCDoublebuffer, XtRBoolean, sizeof (Boolean),
  88.        offset(doublebuffer), XtRImmediate, (XtPointer) FALSE},
  89.   
  90.   {GLwNstereo, GLwCStereo, XtRBoolean, sizeof (Boolean),
  91.        offset(stereo), XtRImmediate, (XtPointer) FALSE},
  92.   
  93.   {GLwNauxBuffers, GLwCAuxBuffers, XtRInt, sizeof (int),
  94.        offset(auxBuffers), XtRImmediate, (XtPointer) 0},
  95.   
  96.   {GLwNredSize, GLwCColorSize, XtRInt, sizeof (int),
  97.        offset(redSize), XtRImmediate, (XtPointer) 1},
  98.   
  99.   {GLwNgreenSize, GLwCColorSize, XtRInt, sizeof (int),
  100.        offset(greenSize), XtRImmediate, (XtPointer) 1},
  101.   
  102.   {GLwNblueSize, GLwCColorSize, XtRInt, sizeof (int),
  103.        offset(blueSize), XtRImmediate, (XtPointer) 1},
  104.   
  105.   {GLwNalphaSize, GLwCAlphaSize, XtRInt, sizeof (int),
  106.        offset(alphaSize), XtRImmediate, (XtPointer) 0},
  107.   
  108.   {GLwNdepthSize, GLwCDepthSize, XtRInt, sizeof (int),
  109.        offset(depthSize), XtRImmediate, (XtPointer) 0},
  110.   
  111.   {GLwNstencilSize, GLwCStencilSize, XtRInt, sizeof (int),
  112.        offset(stencilSize), XtRImmediate, (XtPointer) 0},
  113.   
  114.   {GLwNaccumRedSize, GLwCAccumColorSize, XtRInt, sizeof (int),
  115.        offset(accumRedSize), XtRImmediate, (XtPointer) 0},
  116.   
  117.   {GLwNaccumGreenSize, GLwCAccumColorSize, XtRInt, sizeof (int),
  118.        offset(accumGreenSize), XtRImmediate, (XtPointer) 0},
  119.   
  120.   {GLwNaccumBlueSize, GLwCAccumColorSize, XtRInt, sizeof (int),
  121.        offset(accumBlueSize), XtRImmediate, (XtPointer) 0},
  122.   
  123.   {GLwNaccumAlphaSize, GLwCAccumAlphaSize, XtRInt, sizeof (int),
  124.        offset(accumAlphaSize), XtRImmediate, (XtPointer) 0},
  125.   
  126.   /* the attribute list */
  127.   {GLwNattribList, GLwCAttribList, XtRPointer, sizeof(int *),
  128.        offset(attribList), XtRImmediate, (XtPointer) NULL},
  129.  
  130.   /* the visual info */
  131.   {GLwNvisualInfo, GLwCVisualInfo, GLwRVisualInfo, sizeof (XVisualInfo *),
  132.        offset(visualInfo), XtRImmediate, (XtPointer) NULL},
  133.  
  134. /* miscellaneous resources */
  135.   {GLwNinstallColormap, GLwCInstallColormap, XtRBoolean, sizeof (Boolean),
  136.        offset(installColormap), XtRImmediate, (XtPointer) TRUE},
  137.  
  138.   {GLwNallocateBackground, GLwCAllocateColors, XtRBoolean, sizeof (Boolean),
  139.        offset(allocateBackground), XtRImmediate, (XtPointer) FALSE},
  140.  
  141.   {GLwNallocateOtherColors, GLwCAllocateColors, XtRBoolean, sizeof (Boolean),
  142.        offset(allocateOtherColors), XtRImmediate, (XtPointer) FALSE},
  143.  
  144.   {GLwNinstallBackground, GLwCInstallBackground, XtRBoolean, sizeof (Boolean),
  145.        offset(installBackground), XtRImmediate, (XtPointer) TRUE},
  146.  
  147.   {GLwNginitCallback, GLwCCallback, XtRCallback, sizeof (XtCallbackList),
  148.        offset(ginitCallback), XtRImmediate, (XtPointer) NULL},
  149.  
  150.   {GLwNinputCallback, GLwCCallback, XtRCallback, sizeof (XtCallbackList),
  151.        offset(inputCallback), XtRImmediate, (XtPointer) NULL},
  152.  
  153.   {GLwNresizeCallback, GLwCCallback, XtRCallback, sizeof (XtCallbackList),
  154.        offset(resizeCallback), XtRImmediate, (XtPointer) NULL},
  155.  
  156.   {GLwNexposeCallback, GLwCCallback, XtRCallback, sizeof (XtCallbackList),
  157.        offset(exposeCallback), XtRImmediate, (XtPointer) NULL},
  158.  
  159. #ifdef __GLX_MOTIF
  160.   /* Changes to Motif primitive resources */
  161.   {XmNtraversalOn, XmCTraversalOn, XmRBoolean, sizeof (Boolean),
  162.        XtOffset (GLwDrawingAreaWidget, primitive.traversal_on), XmRImmediate,
  163.        (XtPointer) FALSE},
  164.   
  165.   /* highlighting is normally disabled, as when Motif tries to disable
  166.    * highlighting, it tries to reset the color back to the parent's
  167.    * background (usually Motif blue).  Unfortunately, that is in a
  168.    * different colormap, and doesn't work too well.
  169.    */
  170.   {XmNhighlightOnEnter, XmCHighlightOnEnter, XmRBoolean, sizeof (Boolean),
  171.        XtOffset (GLwDrawingAreaWidget, primitive.highlight_on_enter),
  172.        XmRImmediate, (XtPointer) FALSE},
  173.   
  174.   {XmNhighlightThickness, XmCHighlightThickness, XmRHorizontalDimension,
  175.        sizeof (Dimension),
  176.        XtOffset (GLwDrawingAreaWidget, primitive.highlight_thickness),
  177.        XmRImmediate, (XtPointer) 0},
  178.  
  179. #endif /* __GLX_MOTIF */
  180. };
  181.  
  182. /* The following resources are reobtained using XtGetApplicationResources
  183.  * in the initialize proc.
  184.  */
  185. /* The colormap */
  186. static XtResource initializeResources[] = {
  187.   /* reobtain the colormap with the new visual */
  188.   {XtNcolormap, XtCColormap, XtRColormap, sizeof(Colormap),
  189.        XtOffset(GLwDrawingAreaWidget, core.colormap),
  190.      XtRCallProc,(XtPointer) createColormap},
  191. };
  192.  
  193. /* reallocate any colors we need in the new colormap */
  194.   
  195. /* The background is obtained only if the allocateBackground resource is TRUE*/
  196. static XtResource backgroundResources[] = {
  197. #ifdef __GLX_MOTIF
  198.    {
  199.      XmNbackground, XmCBackground, XmRPixel, 
  200.      sizeof (Pixel), XtOffset(GLwDrawingAreaWidget, core.background_pixel),
  201.      XmRCallProc, (XtPointer) _XmBackgroundColorDefault
  202.    },
  203.    {
  204.      XmNbackgroundPixmap, XmCPixmap, XmRXmBackgroundPixmap, 
  205.      sizeof (Pixmap), XtOffset(GLwDrawingAreaWidget, core.background_pixmap),
  206.      XmRImmediate, (XtPointer) XmUNSPECIFIED_PIXMAP
  207.    },
  208.  
  209. #else    /* ! __GLX_MOTIF */
  210.     {XtNbackground, XtCBackground, XtRPixel,sizeof(Pixel),
  211.          XtOffset(GLwDrawingAreaWidget,core.background_pixel),
  212.      XtRString, (XtPointer)"XtDefaultBackground"},
  213.     {XtNbackgroundPixmap, XtCPixmap, XtRPixmap, sizeof(Pixmap),
  214.          XtOffset(GLwDrawingAreaWidget,core.background_pixmap),
  215.      XtRImmediate, (XtPointer)XtUnspecifiedPixmap},
  216. #endif  /* __GLX_MOTIF */
  217. };
  218.  
  219. /* The other colors such as the foreground are allocated only if
  220.  * allocateOtherColors are set.  These resources only exist in Motif.
  221.  */
  222.  
  223. #ifdef __GLX_MOTIF
  224. static XtResource otherColorResources[] = {
  225.    {
  226.      XmNforeground, XmCForeground, XmRPixel, 
  227.      sizeof (Pixel), XtOffset(GLwDrawingAreaWidget, primitive.foreground),
  228.      XmRCallProc, (XtPointer) _XmForegroundColorDefault
  229.    },
  230.  
  231.    {
  232.      XmNhighlightColor, XmCHighlightColor, XmRPixel, sizeof (Pixel),
  233.      XtOffset(GLwDrawingAreaWidget, primitive.highlight_color),
  234.      XmRCallProc, (XtPointer) _XmHighlightColorDefault
  235.    },
  236.  
  237.    {
  238.      XmNhighlightPixmap, XmCHighlightPixmap, XmRPrimHighlightPixmap,
  239.      sizeof (Pixmap),
  240.      XtOffset(GLwDrawingAreaWidget, primitive.highlight_pixmap),
  241.      XmRCallProc, (XtPointer) _XmPrimitiveHighlightPixmapDefault
  242.    },
  243. };
  244. #endif /* __GLX_MOTIF */
  245.  
  246. struct attribInfo
  247. {
  248.     int offset;
  249.     int attribute;
  250. };
  251.  
  252. static struct attribInfo intAttribs[] =
  253. {
  254.     { offset(bufferSize), GLX_BUFFER_SIZE },
  255.     { offset(level), GLX_LEVEL },
  256.     { offset(auxBuffers), GLX_AUX_BUFFERS },
  257.     { offset(redSize), GLX_RED_SIZE },
  258.     { offset(greenSize), GLX_GREEN_SIZE },
  259.     { offset(blueSize), GLX_BLUE_SIZE },
  260.     { offset(alphaSize), GLX_ALPHA_SIZE },
  261.     { offset(depthSize), GLX_DEPTH_SIZE },
  262.     { offset(stencilSize), GLX_STENCIL_SIZE },
  263.     { offset(accumRedSize), GLX_ACCUM_RED_SIZE },
  264.     { offset(accumGreenSize), GLX_ACCUM_GREEN_SIZE },
  265.     { offset(accumBlueSize), GLX_ACCUM_BLUE_SIZE },
  266.     { offset(accumAlphaSize), GLX_ACCUM_ALPHA_SIZE },
  267.     { 0, None },
  268. };
  269.  
  270. static struct attribInfo booleanAttribs[] =
  271. {
  272.     { offset(rgba), GLX_RGBA },
  273.     { offset(doublebuffer), GLX_DOUBLEBUFFER },
  274.     { offset(stereo), GLX_STEREO },
  275.     { 0, None },
  276. };
  277.  
  278. #undef offset
  279.  
  280.  
  281. GLwDrawingAreaClassRec glwDrawingAreaClassRec =
  282. {
  283.   { /* core fields */
  284. #ifdef __GLX_MOTIF
  285.     /* superclass        */    (WidgetClass) &xmPrimitiveClassRec,
  286.     /* class_name        */    "GLwMDrawingArea",
  287. #else /* not __GLX_MOTIF */
  288.     /* superclass        */    (WidgetClass) &widgetClassRec,
  289.     /* class_name        */    "GLwDrawingArea",
  290. #endif /* __GLX_MOTIF */
  291.     /* widget_size        */    sizeof(GLwDrawingAreaRec),
  292.     /* class_initialize        */    NULL,
  293.     /* class_part_initialize    */    NULL,
  294.     /* class_inited        */    FALSE,
  295.     /* initialize        */    (XtInitProc) Initialize,
  296.     /* initialize_hook        */    NULL,
  297.     /* realize            */    Realize,
  298.     /* actions            */    actions,
  299.     /* num_actions        */    XtNumber(actions),
  300.     /* resources        */    resources,
  301.     /* num_resources        */    XtNumber(resources),
  302.     /* xrm_class        */    NULLQUARK,
  303.     /* compress_motion        */    TRUE,
  304.     /* compress_exposure    */    TRUE,
  305.     /* compress_enterleave    */    TRUE,
  306.     /* visible_interest        */    TRUE,
  307.     /* destroy            */    (XtWidgetProc) Destroy,
  308.     /* resize            */    (XtWidgetProc) Resize,
  309.     /* expose            */    (XtExposeProc) Redraw,
  310.     /* set_values        */    NULL,
  311.     /* set_values_hook        */    NULL,
  312.     /* set_values_almost    */    XtInheritSetValuesAlmost,
  313.     /* get_values_hook        */    NULL,
  314.     /* accept_focus        */    NULL,
  315.     /* version            */    XtVersion,
  316.     /* callback_private        */    NULL,
  317.     /* tm_table            */    defaultTranslations,
  318.     /* query_geometry        */    XtInheritQueryGeometry,
  319.     /* display_accelerator    */    XtInheritDisplayAccelerator,
  320.     /* extension        */    NULL
  321.   },
  322. #ifdef __GLX_MOTIF /* primitive resources */
  323.   {
  324.     /* border_highlight        */    XmInheritBorderHighlight,
  325.     /* border_unhighlight    */    XmInheritBorderUnhighlight,
  326.     /* translations        */    XtInheritTranslations,
  327.     /* arm_and_activate        */    NULL,
  328.     /* get_resources        */    NULL,
  329.     /* num get_resources    */    0,
  330.     /* extension        */    NULL,                
  331.   }
  332. #endif /* __GLX_MOTIF */
  333. };
  334.  
  335. WidgetClass glwDrawingAreaWidgetClass = (WidgetClass)&glwDrawingAreaClassRec;
  336.  
  337. static error(w,string)
  338. Widget w;
  339. char *string;
  340. {
  341.     char buf[100];
  342. #ifdef __GLX_MOTIF
  343.     sprintf (buf, "GLwMDrawingArea: %s\n", string);
  344. #else
  345.     sprintf (buf, "GLwDrawingArea: %s\n", string);
  346. #endif
  347.     XtAppError(XtWidgetToApplicationContext(w), buf);
  348. }
  349.  
  350. static warning(w,string)
  351. Widget w;
  352. char *string;
  353. {
  354.     char buf[100];
  355. #ifdef __GLX_MOTIF
  356.     sprintf (buf, "GLwMDraw: %s\n", string);
  357. #else
  358.     sprintf (buf, "GLwDraw: %s\n", string);
  359. #endif
  360.     XtAppWarning(XtWidgetToApplicationContext(w), buf);
  361. }
  362.  
  363. /* resource initialization methods */
  364. /* Initialize the attribList based on the attributes */
  365. static void createAttribList(GLwDrawingAreaWidget w)
  366. {
  367.     int listLength;
  368.     register struct attribInfo *ap;
  369.     int *ip;
  370.  
  371.     /* first find out how long a list we need */
  372.     listLength=1;    /* include the terminating NULL */
  373.     for (ap = booleanAttribs; ap->attribute; ap++)
  374.     {
  375.     if (*(Boolean *)(((char *)w)+ap->offset))
  376.         listLength++;    /* one word for a boolean */
  377.     }
  378.     for (ap = intAttribs; ap->attribute; ap++)
  379.     {
  380.     if (*(int *)(((char *)w)+ap->offset))
  381.         listLength+=2;    /* one word for an int */
  382.     }
  383.     w->glwDrawingArea.attribList = (int *)XtMalloc(listLength*sizeof(int));
  384.     ip = w->glwDrawingArea.attribList;
  385.     for (ap = booleanAttribs; ap->attribute; ap++)
  386.     {
  387.     if (*(Boolean *)(((char *)w)+ap->offset))
  388.         *ip++ = ap->attribute;
  389.     }
  390.     for (ap = intAttribs; ap->attribute; ap++)
  391.     {
  392.     if (*(int *)(((char *)w)+ap->offset))
  393.     {
  394.         *ip++ = ap->attribute;
  395.         *ip++ = *(int *)(((char *)w)+ap->offset);
  396.     }
  397.     }
  398.     *ip = None;
  399. }
  400.  
  401. /* Initialize the visualInfo based on the attribute list */
  402. static void createVisualInfo(GLwDrawingAreaWidget w)
  403. {
  404.     static XVisualInfo *visualInfo;
  405.  
  406.     assert(w->glwDrawingArea.attribList);
  407.     w->glwDrawingArea.visualInfo = glXChooseVisual(XtDisplay(w),
  408.                     XScreenNumberOfScreen(XtScreen(w)),
  409.                     w->glwDrawingArea.attribList);
  410.     if (!w->glwDrawingArea.visualInfo)
  411.     error(w,"requested visual not supported");
  412. }
  413.  
  414. /* Initialize the colormap based on the visual info.
  415.  * This routine maintains a cache of visual-infos to colormaps.  If two
  416.  * widgets share the same visual info, they share the same colormap.
  417.  * This function is called by the callProc of the colormap resource entry.
  418.  */
  419. static void createColormap(GLwDrawingAreaWidget w,
  420.                int offset, XrmValue *value)
  421. {
  422.     static struct cmapCache
  423.     {
  424.     Visual *visual;
  425.     Colormap cmap;
  426.     } *cmapCache;
  427.     static int cacheEntries=0;
  428.     static int cacheMalloced=0;
  429.  
  430.     register int i;
  431.     
  432.     assert(w->glwDrawingArea.visualInfo);
  433.  
  434.     /* see if we can find it in the cache */
  435.     for (i=0; i<cacheEntries; i++)
  436.     if (cmapCache[i].visual == w->glwDrawingArea.visualInfo->visual)
  437.     {
  438.         value->addr = (XtPointer) (&cmapCache[i].cmap);
  439.         return;
  440.     }
  441.     /* not in the cache, create a new entry */
  442.     if (cacheEntries >= cacheMalloced)
  443.     {
  444.     /* need to malloc a new one.  Since we are likely to have only a
  445.      * few colormaps, we allocate one the first time, and double
  446.      * each subsequent time.
  447.      */
  448.     if (cacheMalloced == 0)
  449.     {
  450.         cacheMalloced = 1;
  451.         cmapCache = (struct cmapCache *)XtMalloc(sizeof(struct cmapCache));
  452.     }
  453.     else
  454.     {
  455.         cacheMalloced <<= 1;
  456.         cmapCache = (struct cmapCache *)XtRealloc((char *) cmapCache,
  457.                               sizeof(struct cmapCache)*
  458.                               cacheMalloced);
  459.     }
  460.     }
  461.        
  462.     cmapCache[cacheEntries].cmap  = XCreateColormap (XtDisplay(w),
  463.                     RootWindow(XtDisplay(w),
  464.                     w->glwDrawingArea.visualInfo->screen),
  465.                     w->glwDrawingArea.visualInfo->visual,
  466.                     AllocNone);
  467.     cmapCache[cacheEntries].visual = w->glwDrawingArea.visualInfo->visual;
  468.     value->addr = (XtPointer) (&cmapCache[cacheEntries++].cmap);
  469. }
  470.  
  471. static void
  472. Initialize (GLwDrawingAreaWidget req, GLwDrawingAreaWidget new,
  473.         ArgList args, Cardinal *num_args)
  474. {
  475.  
  476.     if (req->core.width == 0)
  477.     new->core.width = 100;
  478.     if (req->core.height == 0)
  479.     new->core.width = 100;
  480.  
  481.     /* create the attribute list if needed */
  482.     if (new->glwDrawingArea.attribList == NULL)
  483.     {
  484.     new->glwDrawingArea.myList = TRUE;
  485.     createAttribList(new);
  486.     }
  487.     else
  488.     new->glwDrawingArea.myList = FALSE;
  489.  
  490.     /* determine the visual info if needed */
  491.     if (new->glwDrawingArea.visualInfo == NULL)
  492.     {
  493.     new->glwDrawingArea.myVisual = TRUE;
  494.     createVisualInfo(new);
  495.     }
  496.     else
  497.     new->glwDrawingArea.myVisual = FALSE;
  498.  
  499.     new->core.depth = new->glwDrawingArea.visualInfo->depth;
  500.  
  501.     /* Reobtain the colormap and colors in it using XtGetApplicationResources*/
  502.     XtGetApplicationResources((Widget) new, new,
  503.                   initializeResources,
  504.                   XtNumber(initializeResources),
  505.                   args, *num_args);
  506.  
  507.     /* obtain the color resources if appropriate */
  508.     if (req->glwDrawingArea.allocateBackground)
  509.     XtGetApplicationResources((Widget) new, new,
  510.                   backgroundResources,
  511.                   XtNumber(backgroundResources),
  512.                   args, *num_args);
  513.  
  514. #ifdef __GLX_MOTIF
  515.     if (req->glwDrawingArea.allocateOtherColors)
  516.     XtGetApplicationResources((Widget) new, new,
  517.                   otherColorResources,
  518.                   XtNumber(otherColorResources),
  519.                   args, *num_args);
  520. #endif /* __GLX_MOTIF */
  521.  
  522. }
  523.  
  524. static void
  525. Realize(Widget w, Mask *valueMask, XSetWindowAttributes *attributes)
  526. {
  527.     register GLwDrawingAreaWidget glw = (GLwDrawingAreaWidget)w;
  528.     GLwDrawingAreaCallbackStruct cb;
  529.    
  530.     /* if we haven't requested that the background be both installed and
  531.      * allocated, don't install it.
  532.      */
  533.     if (!(glw->glwDrawingArea.installBackground &&
  534.       glw->glwDrawingArea.allocateBackground))
  535.     *valueMask &= ~CWBackPixel;
  536.     
  537.     XtCreateWindow (w, (unsigned int)InputOutput,
  538.             glw->glwDrawingArea.visualInfo->visual,
  539.             *valueMask, attributes);
  540.  
  541.     /* if appropriate, call XSetWMColormapWindows to install the colormap */
  542.     if (glw->glwDrawingArea.installColormap)
  543.     {
  544.     Widget parentShell = XtParent(w);
  545.     Status status;
  546.     Window *windowsReturn;
  547.     int countReturn;
  548.     
  549.     while (parentShell && !XtIsShell(parentShell))
  550.         parentShell = XtParent(parentShell);
  551.     if (parentShell && XtWindow(parentShell))
  552.     {
  553.         /* check to see if there is already a property */
  554.         status = XGetWMColormapWindows(XtDisplay(parentShell),
  555.                        XtWindow(parentShell),
  556.                        &windowsReturn, &countReturn);
  557.         
  558.         /* if no property, just create one */
  559.         if (!status)
  560.         {
  561.         Window windows[2];
  562.         windows[0] = XtWindow(w);
  563.         windows[1] = XtWindow(parentShell);
  564.         XSetWMColormapWindows(XtDisplay(parentShell),
  565.                       XtWindow(parentShell),
  566.                       windows, 2);
  567.         }
  568.         /* there was a property, add myself to the beginning */
  569.         else
  570.         {
  571.         Window *windows = (Window *)XtMalloc((sizeof(Window))*
  572.                              (countReturn+1));
  573.         register int i;
  574.         windows[0] = XtWindow(w);
  575.         for (i=0; i<countReturn; i++)
  576.             windows[i+1] = windowsReturn[i];
  577.         XSetWMColormapWindows(XtDisplay(parentShell),
  578.                       XtWindow(parentShell),
  579.                       windows, countReturn+1);
  580.         XtFree((char *) windows);
  581.         XtFree((char *) windowsReturn);
  582.         }
  583.     }
  584.     else
  585.         warning(w, "Could not set colormap property on parent shell");
  586.     }
  587.     cb.reason = GLwCR_GINIT;
  588.     cb.event = NULL;
  589.     cb.width = glw->core.width;
  590.     cb.height = glw->core.height;
  591.     XtCallCallbackList((Widget) glw, glw->glwDrawingArea.ginitCallback, &cb);
  592. }
  593.  
  594. static void
  595. Redraw(GLwDrawingAreaWidget w, XEvent *event, Region region)
  596. {
  597.    GLwDrawingAreaCallbackStruct cb;
  598.    XtCallbackList cblist;
  599.    
  600.    cb.reason = GLwCR_EXPOSE;
  601.    cb.event = event;
  602.    cb.width = w->core.width;
  603.    cb.height = w->core.height;
  604.    XtCallCallbackList ((Widget) w, w->glwDrawingArea.exposeCallback, &cb);
  605. }
  606.  
  607. static void
  608. Resize(GLwDrawingAreaWidget glw)
  609. {
  610.     GLwDrawingAreaCallbackStruct cb;
  611.  
  612.     /* if we get a resize event before being realized, we can't handle it */
  613.     if (!XtIsRealized((Widget)glw))
  614.     return;
  615.    cb.reason = GLwCR_RESIZE;
  616.    cb.event = NULL;
  617.    cb.width = glw->core.width;
  618.    cb.height = glw->core.height;
  619.    XtCallCallbackList ((Widget) glw, glw->glwDrawingArea.resizeCallback, &cb);
  620. }
  621.  
  622. static void
  623. Destroy(GLwDrawingAreaWidget glw)    
  624. {
  625.     if (glw->glwDrawingArea.myList && glw->glwDrawingArea.attribList)
  626.     XtFree ((XtPointer)glw->glwDrawingArea.attribList);
  627.     if (glw->glwDrawingArea.myVisual && glw->glwDrawingArea.visualInfo)
  628.     XtFree ((XtPointer)glw->glwDrawingArea.visualInfo);
  629.  
  630.     /* if my colormap was installed, remove it */
  631.     if (glw->glwDrawingArea.installColormap)
  632.     {
  633.     Widget parentShell = XtParent(glw);
  634.     Status status;
  635.     Window *windowsReturn;
  636.     int countReturn;
  637.     register int i;
  638.     
  639.     /* find the parent shell */
  640.     while (parentShell && !XtIsShell(parentShell))
  641.         parentShell = XtParent(parentShell);
  642.  
  643.     if (parentShell && XtWindow(parentShell))
  644.     {
  645.         /* make sure there is a property */
  646.         status = XGetWMColormapWindows(XtDisplay(parentShell),
  647.                        XtWindow(parentShell),
  648.                        &windowsReturn, &countReturn);
  649.         
  650.         /* if no property, just return.  If there was a property,
  651.          * continue
  652.          */
  653.         if (status)
  654.         {
  655.         /* search for a match */
  656.         for (i=0; i<countReturn; i++)
  657.         {
  658.             if (windowsReturn[i] == XtWindow(glw))
  659.             {
  660.             /* we found a match, now copu the rest down */
  661.             for (i++; i<countReturn; i++)
  662.             {
  663.                 windowsReturn[i-1] = windowsReturn[i];
  664.             }
  665.             XSetWMColormapWindows(XtDisplay(parentShell),
  666.                           XtWindow(parentShell),
  667.                           windowsReturn, countReturn-1);
  668.             break;    /* from outer for */
  669.             }
  670.         }
  671.         XtFree((char *) windowsReturn);
  672.         }
  673.     }
  674.     }
  675. }
  676.  
  677. /* Action routine for keyboard and mouse events */
  678. /* ARGSUSED */
  679. static void glwInput (GLwDrawingAreaWidget glw, XEvent *event,
  680.               String * params, Cardinal * numParams)
  681. {
  682.    GLwDrawingAreaCallbackStruct cb;
  683.    
  684.    cb.reason = GLwCR_INPUT;
  685.    cb.event = event;
  686.    cb.width = glw->core.width;
  687.    cb.height = glw->core.height;
  688.    XtCallCallbackList ((Widget) glw, glw->glwDrawingArea.inputCallback, &cb);
  689. }
  690.  
  691. #ifdef __GLX_MOTIF
  692. /* Provide a Motif-style create routine */
  693. Widget GLwCreateMDrawingArea(Widget parent, char *name,
  694.                  ArgList arglist, Cardinal argcount)
  695. {
  696.     return (XtCreateWidget (name, glwMDrawingAreaWidgetClass, parent, arglist,
  697.                 argcount));
  698. }
  699. #endif
  700.